#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>

#define SERVER_PORT 9986

int main()
{
	int              lisfd=-1,clifd=-1;
	int                        rv=-1;
	struct  sockaddr_in  cli_addr;
	struct  sockaddr_in serv_addr;
	char                 buf[128];
	int                    on =1 ;
	pid_t                     pid;
	socklen_t         cliaddr_len;

	if( (lisfd=socket(AF_INET,SOCK_STREAM,0)) < 0 )
	{
		printf("creat socket falure: %s\n",strerror(errno));
		return -1;
	}
	printf("creat socket[%d] successfully\n",lisfd);

        setsockopt(lisfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	memset(&serv_addr,0,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERVER_PORT);
	serv_addr.sin_addr.s_addr =htonl(INADDR_ANY);

	if( (rv=bind(lisfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))) < 0 )
	{
		printf("bind falure :%s\n",strerror(errno));
		return -2;
	}
	printf("bind successully\n");

	if( (rv=listen(lisfd,15)) < 0)
	{
		printf("listen falure :%s\n",strerror(errno));
		return -3;
	}
	printf("Start to listen on port [%d]\n",SERVER_PORT);

	while(1)
	{
		printf("\nwaitting new client connect...\n");

//		memset(&cli_addr,0,sizeof(cli_addr));


		clifd=accept(lisfd,(struct sockaddr *)&cli_addr,&cliaddr_len);

		if(clifd < 0)
		{
			printf("accept falure :%s\n",strerror(errno));
		//	continue;
			return -7;//为什么整个程序不会退出？
			printf("here 2");
		}
		printf("\naccept client [%d] successfully\n",clifd);

		pid=fork();
		if( pid <0 )
		{
			printf("fork falure :%s\n",strerror(errno));
			return -4;
		}
		else if(pid > 0)
		{
			printf("\nparent process running,go to accept new client now\n");
			close(clifd); 
			continue;
		}
		else if(pid == 0)
		{
			printf("\nthe child of PID[%d] process running\n",getpid());
			close(lisfd); 
			lseek(clifd,0,SEEK_SET);
			memset(buf,0,sizeof(buf));
			if( (rv=read(clifd,buf,sizeof(buf))) < 0)
			{
				printf("read falure :%s\n",strerror(errno));
				return -5;
			}
			printf("read data %d byte,content is:\n%s\n",rv,buf);

			if( (rv=write(clifd,buf,strlen(buf))) < 0 )
			{
				printf("write falure :%s\n",strerror(errno));
				return -6;
			}
			printf("\nwrite data %d byte,content is:\n%s\n",rv,buf);

			close(clifd);
			printf("this child of PID [%d] process is over\n",getpid());
			return 0;//不加return 0；子进程就不会结束，继续执行while，
				 //而lisfd已经被子进程关闭，而accept failure后只有子进程退出了，
				 //而父进程还在运行，所以整个程序不会退出)
		}
	}
	close(clifd);
	return 0;						
}
